/*
 * <h3>Title:wheel-parent系统</h3>
 * <p>Copyright (c) 2019, wnfbx@163.com. All rights reserved.</p>
 * @author wnfbx@163.com
 */
package com.wheel.autoconfigure.dynamicdatasource.datasource;

import com.wheel.autoconfigure.dynamicdatasource.builder.DynamicDataSourceBuilder;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedHashMap;

/**
 * <dt>Description:AbstractDynamicDataSource</dt>
 * <dd> 抽象动态数据源</dd>TODO
 *
 * @author wnfbx@163.com
 * @version 1.0 <i>2019/12/19 16:29</i>
 * @since jdk1.8+
 */
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {

    public static final ThreadLocal<Deque<String>> KEY_HOLDER = ThreadLocal.withInitial(ArrayDeque::new);

    public DynamicRoutingDataSource(DynamicDataSourceBuilder dynamicDataSourceBuilder) {
        this.setTargetDataSources(new LinkedHashMap<>(dynamicDataSourceBuilder.getDataSourceMap()));
    }

    /**
     * <dt>Description:peek</dt>
     * <dd>获取当前数据源</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2020/1/9 14:52</i></dd>
     *
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String peek() {
        return KEY_HOLDER.get().peek();
    }

    /**
     * <dt>Description:push</dt>
     * <dd>设置当前线程数据源
     * <p>如手动调用，调用后确保最终清除</p>
     * </dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2020/1/9 14:52</i></dd>
     *
     * @param ds 数据源名称
     * @since jdk1.7+
     */
    public static void push(String ds) {
        KEY_HOLDER.get().push(ds);
    }

    /**
     * <dt>Description:poll</dt>
     * <dd>清除使用过的数据源名称
     * <p>如果当前线程是连续切换数据源，只会移除最后一次切换的数据源名称</p>
     * </dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2020/1/9 14:54</i></dd>
     *
     * @since jdk1.7+
     */
    public static void poll() {
        Deque<String> deque = KEY_HOLDER.get();
        deque.poll();
        if (deque.isEmpty()) {
            clear();
        }
    }

    /**
     * <dt>Description:clear</dt>
     * <dd>强制清空本地线程
     * <p>防止内存泄漏，如手动调用了push可调用此方法确保清除</p>
     * </dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2020/1/9 14:57</i></dd>
     *
     * @since jdk1.7+
     */
    public static void clear() {
        KEY_HOLDER.remove();
    }

    /**
     * <dt>Description:getLast</dt>
     * <dd>获取最后一个并且不删除</dd>
     * <dd>author: wnfbx@163.com</dd>
     * <dd>version:1.0 <i>2020/1/9 19:11</i></dd>
     *
     * @return java.lang.String
     * @since jdk1.7+
     */
    public static String getLast() {
        Deque<String> deque = KEY_HOLDER.get();
        if (deque.isEmpty()) {
            return null;
        }
        return deque.getLast();
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return peek();
    }
}
